package org.luxor.commons.core.web;

import org.luxor.commons.core.utils.Jackson2Utils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 异常状态码定义
 * <p>
 * 建议规格：{1位,范围分级}+{2位,项目编码}+{2位,模块编码}+{3位,错误码} = 8位固定码
 * <p>
 * 含义说明
 * 1.范围分级：固定1位，代表引起异常原因的所属边界范围 (1 代表系统自身缺陷; 2 代表调用方不合规操作; 3 代表外部支撑端故障)
 * 2.项目编码：固定2位，项目分类编码
 * 3.模块编码：固定2位，项目模块编码
 * 4.错误编码：固定3位，自定义异常码
 *
 * @author XinmingYan @date 2019/9/16
 */
public enum RestStatus implements IRestStatus {
    // 系统自身异常
    SUCCESS(0, "执行成功"),
    ERROR(10100000, "执行失败"),

    UNKNOWN(10101001, "服务异常,请联系管理员"),
    UPGRADES(10101002, "暂不可用,请稍后再试"),

    UNAUTHORIZED(10103003, "未授权访问"),
    FORBIDDEN(10103004, "禁止访问"),
    INVALID_GRANT(10103005, "无效授权"),
    NOT_FOUND(10103006, "内容不存在"),

    METHOD_NOT_ALLOWED(10101007, "方法不支持"),
    SERVER_ERROR(10101008, "服务不可用"),
    SERVER_HYSTRIX(10101009, "服务熔断"),

    SQL_GRAMMAR(10104010, "SQL语句执行出错"),
    TRANSACTIONAL(10104011, "事务回滚异常"),
    EXISTS_KEY(10104012, "数据存在重复记录"),
    NOT_EXIST_DATA(10104013, "数据不存在"),

    GET_GLOBAL_LOCK_TIMEOUT(10107009, "获取加锁资源超时"),

    // 上游调用方异常
    LIMIT_RATE_ERROR(20107001, "操作过于频繁,请稍后再试"),
    IDEMPOTENT_ERROR(20107002, "非法请求，请勿重复操作"),

    PARAM_ILLEGAL_FIELDS(20102003, "请求参数不合法"),
    PARAM_ILLEGAL_CONVERSION(20102004, "请求参数类型转换异常"),
    JSON_INVALID_PARSE(20102005, "JSON解析错误"),
    SIGN_ERROR(20102006, "接口签名验证错误"),
    ENCRYPT_ERROR(20102007, "接口报文加解密异常"),
    TOKEN_INVALID(20102008, "身份凭证无效或已过期"),

    // 下游支撑方异常
    RPC_CALL_ERROR(30101001, "内部支撑服务故障"),
    FEIGN_HYSTRIX(30101002, "内部支撑服务熔断");

    private final Integer code;
    private final String message;

    RestStatus(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    @Override
    public int code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }

    public Map<String, Object> asMap() {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("code", this.code);
        map.put("message", this.message);
        return map;
    }

    public String toJson() {
        return Jackson2Utils.toJson(asMap());
    }
}

